package com.authine.cloudpivot.ext.kingdee.work;

import com.alibaba.cola.dto.SingleResponse;
import com.authine.cloudpivot.ext.constants.KingDeeConstant;
import com.authine.cloudpivot.ext.dto.kingDee.KingDeeBusiness;
import com.authine.cloudpivot.ext.dto.kingDee.request.*;
import com.authine.cloudpivot.ext.dto.voucher.Voucher;
import com.authine.cloudpivot.ext.enums.kingdee.BusinessType;
import com.authine.cloudpivot.ext.enums.kingdee.FAccountIdEnum;
import com.authine.cloudpivot.ext.enums.kingdee.FormEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: liwei
 * @DateTime: 2021/7/16
 * @Description: TODO
 */
@Slf4j
public class TransferPurchaseWork extends BaseWork {


    /* 转采退货生成凭证 */
    public SingleResponse purchaseReturnCertificate( KingDeeMemberPurchaseOrder memberPurchaseOrder) {
        log.info("转采退货生成凭证  request:{}", memberPurchaseOrder);
        //退货生成凭证
        List<Voucher> voucherList = new ArrayList<>();
        //po号
        String poCode = memberPurchaseOrder.getPoCode();
        //采购总价（未税）
        BigDecimal prePurchaseAmount = memberPurchaseOrder.getPrePurchaseAmount();
        //是否退货单
        if (memberPurchaseOrder.getIsRp()) {
            Voucher v1 = Voucher.builder().business_id(poCode)
                    .business_type(BusinessType.TransferReturnOrder)
                    .remark("采购退货")
                    .subject_coding(FAccountIdEnum.accounts060301.getFNumber())
                    .debit_amount(prePurchaseAmount)
                    .credit_amount(BigDecimal.ZERO)
                    .account_name(memberPurchaseOrder.getAccountName())
                    .del(false)
                    .version("0")
                    .build();

            voucherList.add(v1);

            for (KingDeeMemberPurchaseOrderGood item : memberPurchaseOrder.getKingDeeMemberPurchaseOrderGoods()) {

                Voucher.builder().business_id(poCode)
                        .business_type(BusinessType.TransferReturnOrder)
                        .remark("采购退货")
                        .subject_coding(FAccountIdEnum.payable0102.getFNumber())
                        .debit_amount(BigDecimal.ZERO)
                        .credit_amount(item.getPretaxAmount())
                        .account_name(memberPurchaseOrder.getAccountName())
                        .del(false)
                        .version("0")
                        .build();

                voucherList.add(v1);
            }
        }
        saveVoucherList(voucherList);
        log.info("转采退货生成凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }

    /* 转采确认付款生成凭证 */
    public SingleResponse paymentCredentialGeneration( List<KingDeeRequestPayment> kingDeeRequestPaymentList) {
        log.info("转采确认付款生成凭证  request:{}", kingDeeRequestPaymentList);

        List<FEntity> fEntityList = new ArrayList<>();
        String accountName = kingDeeRequestPaymentList.get(0).getAccountName();
        for (KingDeeRequestPayment payment : kingDeeRequestPaymentList) {
            //获取支付详情
            List<KingDeeRequestPaymentDetail> detailList = payment.getKingDeeRequestPaymentDetailList();
            //采购供应商名称
            String vendorName = payment.getTransferVendorName();
            //供应商id
            String vendorId = payment.getVendorId();
            //采购编号
            List<String> poList = detailList.stream().map(KingDeeRequestPaymentDetail::getPoCode).collect(Collectors.toList());

            //金蝶的摘要字段有长度限制，这里的业务数据可能很多 所以做了一些截取
            if (poList.size() > 3) {
                poList = poList.subList(0, 3);
            }

            String poCode = String.join(",", poList);
            BigDecimal paymentAmount = payment.getPaymentAmount();
            int subject = payment.getInvoiceApplyTypeEnum().subject;
            // 摘要
            String remark = "采购单号：--" + poCode + "--付货款--" + vendorName;


            if (detailList.size() >= 2) {
                if (detailList.get(0).getPaymentDetailAmount() == null) {
                    FEntity f1 = FEntity.addFentity();
                    f1.setFExplanation(remark);
                    f1.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.payable0101.getFNumber()));
                    f1.setFDetailIdEntity(FDetailIdEntity.addFDetailID4(vendorId));
                    f1.setFDebit(paymentAmount);

                    fEntityList.add(f1);
                } else {
                    detailList.forEach(e -> {
                        FEntity f2 = FEntity.addFentity();
                        f2.setFExplanation("采购单号：--" + e.getPoCode() + "--付货款--" + vendorName);
                        f2.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.payable0101.getFNumber()));
                        f2.setFDetailIdEntity(FDetailIdEntity.addFDetailID4(vendorId));
                        f2.setFDebit(e.getPaymentDetailAmount());
                        fEntityList.add(f2);

                    });
                }
            }

            if (detailList.size() == 1) {
                FEntity f3 = FEntity.addFentity();
                f3.setFExplanation(remark);
                f3.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.payable0101.getFNumber()));
                f3.setFDetailIdEntity(FDetailIdEntity.addFDetailID4(vendorId));
                f3.setFDebit(paymentAmount);
                fEntityList.add(f3);
            }

            FEntity f4 = FEntity.addFentity();
            f4.setFExplanation(remark);
            f4.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.getDes(subject)));
            String replace = payment.getBankNumber().replace(" ", "");
            f4.setFDetailIdEntity(FDetailIdEntity.addBank(replace));

            if (paymentAmount.compareTo(BigDecimal.ZERO) == -1) {
                f4.setFDebit(paymentAmount.negate());
            } else {
                f4.setFCredit(paymentAmount);
            }

            fEntityList.add(f4);

            KingDeeBusiness kingDeeBusiness = new KingDeeBusiness(payment.getId(), null, BusinessType.TransferPaymentSlip, payment.getFinancialConfirmTime(), null, accountName);

            KingDeeEntity kingDeeEntity = getKingDeeEntity(fEntityList, kingDeeBusiness);

            doSaveKingDeeAndRecord(FormEnum.VOUCHER, kingDeeEntity, kingDeeBusiness);
        }
        log.info("转采确认付款生成凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }

    /*  转采确认收票生成凭证 */
    public SingleResponse receiptCredentialGeneration( List<KingDeePurchaseReceipt> kingDeePurchaseReceiptList) {
        log.info("转采确认收票生成凭证  request:{}", kingDeePurchaseReceiptList);

        // 4.1 暂估冲回凭证
        List<FEntity> rushBackList = new ArrayList<>();
        // 4.2 采购发票
        List<FEntity> purchaseInvoiceList = new ArrayList<>();
        // 增补分录
        List<FEntity> tradeList = new ArrayList<>();

        kingDeePurchaseReceiptList.forEach(e -> {

            // 供应商名称
            String companyName = e.getCompanyName();
            // 供应商ID
            String vendorOrgId = e.getVendorOrgId();
            // po号拼接
            String poCode = e.getPurchaseInvoiceDetailList().get(0).getPoCode();
            // 供应商订单id
            String vendorOrderId = "";
            // 根据税率取对应的科目
            Integer tax = getIntoTax(e.getInvoiceRate());
            // 采购摘要
            String explanation = "采购单号：" + poCode + "--采购--" + companyName;
            BigDecimal balanceAmount = new BigDecimal(0.0);
            // 4.3  库存商品-转采
            FEntity fEntity2 = FEntity.addFentity();
            fEntity2.setFExplanation(explanation);
            fEntity2.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.stock02.getFNumber()));
            fEntity2.setFDetailIdEntity(FDetailIdEntity.addFDetailID4(vendorOrgId));
            // 开发确认之前的代码 if 条件可以去掉
            fEntity2.setFDebit(e.getPreInvoiceAmount());

            purchaseInvoiceList.add(fEntity2);

            for (KingDeePurchaseReceiptDetail detail : e.getPurchaseInvoiceDetailList()) {

                balanceAmount = balanceAmount.add(detail.getBalanceAmount());
                vendorOrderId = detail.getVendorOrderId();

                if (null != tax && 0 != tax) {

                    if (detail.getTaxAmount().compareTo(BigDecimal.ZERO) != 0) {

                        FEntity fEntity3 = FEntity.addFentity();
                        fEntity3.setFExplanation(explanation);
                        fEntity3.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.getDes(tax)));

                        if (e.getInvoiceAmount().compareTo(BigDecimal.ZERO) > 0) {

                            fEntity3.setFDebit(detail.getTaxAmount());

                        } else {
                            fEntity3.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.tax0104.getFNumber()));
                            fEntity3.setFCredit(detail.getTaxAmount().negate());
                        }
                        purchaseInvoiceList.add(fEntity3);
                    }
                }

            }

            if (e.getPoDetail().size() != 0) {
                for (Map.Entry<String, BigDecimal> entry : e.getPoDetail().entrySet()) {
                    // 4.2 采购普通发票 应付账款-云平台转采-供应商
                    FEntity fEntity4 = FEntity.addFentity();
                    fEntity4.setFExplanation("采购单号：" + entry.getKey() + "--采购--" + companyName);
                    fEntity4.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.payable0101.getFNumber()));
                    fEntity4.setFDetailIdEntity(FDetailIdEntity.addFDetailID4(vendorOrgId));
                    // 含税金额
                    fEntity4.setFCredit(entry.getValue());
                    purchaseInvoiceList.add(fEntity4);
                }
            }

            if (e.getPoDetail().size() == 0) {
                // 4.2 采购普通发票 应付账款-云平台转采-供应商
                FEntity fEntity5 = FEntity.addFentity();
                fEntity5.setFExplanation(explanation);
                fEntity5.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.payable0101.getFNumber()));
                fEntity5.setFDetailIdEntity(FDetailIdEntity.addFDetailID4(vendorOrgId));
                // 含税金额
                fEntity5.setFCredit(e.getInvoiceAmount());
                purchaseInvoiceList.add(fEntity5);
            }

            // 4.1 应付账款-云平台转采-暂估应付
            FEntity fe2 = FEntity.addFentity();
            fe2.setFExplanation("供应商订单号：" + vendorOrderId + "--暂估冲回--" + companyName);
            fe2.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.payable0102.getFNumber()));
            // 不含税金额（负数）
            fe2.setFCredit(e.getPreOrderAmount().negate());
            rushBackList.add(fe2);


            // 4.1 库存商品-转采
            FEntity fe1 = FEntity.addFentity();
            fe1.setFExplanation("供应商订单号：" + vendorOrderId + "--暂估冲回--" + companyName);
            fe1.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.stock02.getFNumber()));
            // 不含税金额汇总
            fe1.setFDebit(e.getPreOrderAmount().negate());
            rushBackList.add(fe1);
            // 补差
            String tradeExplanation = "供应商订单号：" + vendorOrderId + "--补差";

            if (balanceAmount.compareTo(BigDecimal.ZERO) != 0) {
                // 增补金额 = 收票金额 - 采购金额
                // 增补金额 = 库存商品 + 暂估
                BigDecimal subtract = e.getPreOrderAmount().subtract(e.getPreOrderAmount());
                balanceAmount = subtract.divide(BigDecimal.ONE, 2, RoundingMode.HALF_UP);

                // 主营业务成本-云平台  5401.02
                FEntity trade1 = FEntity.addFentity();
                trade1.setFExplanation(tradeExplanation);
                trade1.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.main02.getFNumber()));
                trade1.setFDetailIdEntity(FDetailIdEntity.addDetailID6("bucha"));
                trade1.setFDebit(balanceAmount);
                tradeList.add(trade1);

                // 库存商品—云平台 1405.01
                FEntity trade2 = FEntity.addFentity();
                trade2.setFExplanation(tradeExplanation);
                trade2.setFAccountId(FAccountIdEntity.faccount(FAccountIdEnum.stock02.getFNumber()));
                trade2.setFCredit(balanceAmount);
                tradeList.add(trade2);
            }

            Collections.reverse(rushBackList);
            purchaseInvoiceList.addAll(rushBackList);
            purchaseInvoiceList.addAll(tradeList);

            // 需求GOMRO-5497 平台附件数为发票条目为N，凭证为N
            Integer attachments = e.getPurchaseInvoiceDetailList().size();
            //淘宝网附件数淘宝网的发票条目为N，凭证为N+1
            if (companyName.equals(KingDeeConstant.COMPANY_NAME_TAOBAOWANG)){
                attachments=e.getPurchaseInvoiceDetailList().size() + 1;
            }

            KingDeeBusiness business = new KingDeeBusiness(e.getId(), poCode, BusinessType.TransferTicket, e.getFinancialConfirmTime(), attachments, kingDeePurchaseReceiptList.get(0).getAccountName());

            KingDeeEntity kingDeeEntity = getKingDeeEntity(purchaseInvoiceList, business);

            doSaveKingDeeAndRecord(FormEnum.VOUCHER, kingDeeEntity, business);

            rushBackList.clear();
            purchaseInvoiceList.clear();
        });

        log.info("转采确认收票生成凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }



    /* 取消付款删除凭证 */
    public SingleResponse cancelPaymentDeletionVoucher(List<KingDeeCancelPayment> kingDeeCancelPayments) {
        log.info("取消付款删除凭证  request:{}", kingDeeCancelPayments);

        kingDeeCancelPayments.forEach(e -> {
            deleteRecordAndUpdate(e.getId(), BusinessType.TransferPaymentSlip, e.getAccountName());
        });

        log.info("取消付款删除凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }

    /* 转采取消收票删除凭证 */
    public SingleResponse purchaseCancelBillingDeleteVoucher( List<KingDeeCancelPayment> kingDeeCancelPayments) {
        log.info("转采取消收票删除凭证  request:{}", kingDeeCancelPayments);

        kingDeeCancelPayments.forEach(e -> {
            deleteRecordAndUpdate(e.getId(), BusinessType.TransferTicket, e.getAccountName());
        });

        log.info("转采取消收票删除凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }

    /* 修改收票时间凭证 */
    public SingleResponse modifyTheInvoiceTimeToGenerateTheVoucher( KingDeePurchaseReceipt purchaseInvoice) {
        log.info("修改收票时间凭证  request:{}", purchaseInvoice);

        deleteRecordAndUpdate(purchaseInvoice.getId(), BusinessType.TransferTicket, purchaseInvoice.getAccountName());

        List<KingDeePurchaseReceipt> receiptList = new ArrayList<>();
        receiptList.add(purchaseInvoice);
        // todo 转采收票生成凭证
        receiptCredentialGeneration(receiptList);

        log.info("修改收票时间凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }


    /* 修改付款时间凭证 */
    public SingleResponse modifyPaymentTimeVoucher( KingDeeRequestPayment kingDeeRequestPayment) {
        log.info("修改付款时间凭证  request:{}", kingDeeRequestPayment);

        deleteRecordAndUpdate(kingDeeRequestPayment.getId(), BusinessType.TransferPaymentSlip, kingDeeRequestPayment.getAccountName());
        // todo 转采-确认付款生成凭证
        paymentCredentialGeneration(Arrays.asList(kingDeeRequestPayment));

        log.info("修改付款时间凭证 >>> 执行完毕");
        return SingleResponse.buildSuccess();
    }
}
